﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Runtime.Serialization;

using zijian666.Converts.Abstractions;

//using System.Runtime.Remoting;

namespace zijian666.Converts.Dynamic;

/// <summary>
/// 基于 <seealso cref="IList" /> 的动态类型
/// </summary>
internal class DynamicList : DynamicObjectBase<IList>, IList, IObjectReference //, IObjectHandle, ICustomTypeProvider
{
    private static readonly IEnumerable<string> _dynamicMemberNames =
        new List<string> { "Count", "Length" }.AsReadOnly();

    public DynamicList(IList value, IConvertSettings convertSettings)
        : base(value, convertSettings)
    {
        if (value is null)
        {
            throw new ArgumentNullException(nameof(value));
        }
    }

    public override bool IsReadOnly => Value!.IsReadOnly;

    int IList.Add(object value) => Value!.Add(value);

    void IList.Clear() => Value!.Clear();

    bool IList.Contains(object value) => Value!.Contains(value);

    int IList.IndexOf(object value) => Value!.IndexOf(value);

    void IList.Insert(int index, object value) => Value!.Insert(index, value);

    bool IList.IsFixedSize => Value!.IsFixedSize;

    void IList.Remove(object value) => Value!.Remove(value);

    void IList.RemoveAt(int index) => Value!.RemoveAt(index);

    object IList.this[int index]
    {
        get
        {
            if ((index >= 0) && (index < Value!.Count))
            {
                return CreateDynamic(Value![index]);
            }

            return DynamicPrimitive.Null;
        }
        set => Value![index] = value;
    }

    void ICollection.CopyTo(Array array, int index) => Value!.CopyTo(array, index);

    int ICollection.Count => Value!.Count;

    bool ICollection.IsSynchronized => Value!.IsSynchronized;

    object ICollection.SyncRoot => Value!;

    IEnumerator IEnumerable.GetEnumerator()
    {
        foreach (var item in Value!)
        {
            if (item is null)
            {
                yield return DynamicPrimitive.Null;
            }

            yield return CreateDynamic(item);
        }
    }

    /// <summary>
    /// 返回所有动态成员名称的枚举。
    /// </summary>
    /// <returns> 一个包含动态成员名称的序列。 </returns>
    public override IEnumerable<string> GetDynamicMemberNames() => _dynamicMemberNames;

    public override bool TryConvert(ConvertBinder binder, out object? result)
    {
        if ((Value!.Count == 1) && TryChangeType(Value[0], binder.ReturnType, out result))
        {
            return true;
        }
        return TryChangeType(Value, binder.ReturnType, out result);
    }

    protected override object? this[int index]
    {
        get => Value![index];
        set => Value![index] = value;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object? result)
    {
        if ("count".Equals(binder.Name, StringComparison.OrdinalIgnoreCase)
            || "length".Equals(binder.Name, StringComparison.OrdinalIgnoreCase))
        {
            result = Value!.Count;
            return true;
        }

        result = null;
        return false;
    }
}
